package com.onec.service.trade.service.online.base;

import com.onec.service.api.dto.request.channel.ChannelTradeReq;
import com.onec.service.api.dto.request.customer.AgentInfoReq;
import com.onec.service.api.dto.request.gateway.BizContent;
import com.onec.service.api.dto.request.route.RouteReq;
import com.onec.service.api.dto.response.BaseResponse;
import com.onec.service.api.dto.response.channel.ChannelTradeResp;
import com.onec.service.api.dto.response.customer.AgentInfoResp;
import com.onec.service.api.dto.response.customer.MerchantResp;
import com.onec.service.api.dto.response.route.RouteResp;
import com.onec.service.api.dto.response.trade.OnlineOrderResp;
import com.onec.service.api.enums.error.TradeErrorEnum;
import com.onec.service.api.exception.TradeException;
import com.onec.service.api.service.channel.ChannelTradeApiService;
import com.onec.service.api.service.customer.AgentInfoApiService;
import com.onec.service.api.service.customer.MerchantInfoApiService;
import com.onec.service.api.service.route.RouteRiskApiService;
import com.onec.service.trade.entity.OnlineOrder;
import com.onec.service.trade.service.BankInfoService;
import com.onec.service.trade.service.KBinInfoService;
import com.onec.service.trade.service.OnlineOrderService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import java.util.Objects;


/**
 * @author ONEC
 */
public abstract class BaseOnlineDefaultService implements OnlineBaseService {

    private static final Logger logger = LoggerFactory.getLogger(BaseOnlineDefaultService.class);

    @DubboReference(version = "1.0.1")
    protected MerchantInfoApiService merchantInfoApiService;

    @DubboReference(version = "1.0.1")
    protected AgentInfoApiService agentInfoApiService;

    @DubboReference(version = "1.0.1")
    protected RouteRiskApiService routeRiskApiService;

    @DubboReference(version = "1.0.1")
    protected ChannelTradeApiService channelTradeApiService;


    @Autowired
    protected ApplicationContext applicationContext;
    @Autowired
    protected RabbitTemplate rabbitTemplate;
    @Autowired
    protected OnlineOrderService onlineOrderService;
    @Autowired
    protected KBinInfoService kBinInfoService;
    @Autowired
    protected BankInfoService bankInfoService;

    /**
     * 通过业务和商户编号获取customer服务商户信息：
     *
     * @param merchantNo
     * @param businessNo
     * @return
     */
    protected MerchantResp getAvailableMerchant(String merchantNo, String businessNo) {
        MerchantResp merchantResp = merchantInfoApiService
                .getMerchantBusiness(merchantNo, businessNo);
        if (!merchantResp.isSuccess()) {
            throw new TradeException(merchantResp.getCode(), merchantResp.getMessage());
        }
        return merchantResp;
    }

    /**
     * 通过业务和商户编号获取customer服务商户信息：
     *
     * @param
     * @param businessNo
     * @return
     */
    protected AgentInfoResp getAvailableAgentBusiness(String agentNo, String businessNo) {
        AgentInfoReq agentInfoReq = new AgentInfoReq();
        agentInfoReq.setAgentCode(agentNo);
        agentInfoReq.setBusinessNo(businessNo);
        AgentInfoResp agentInfoResp = agentInfoApiService.getAgentBusiness(agentInfoReq);
        if (!agentInfoResp.isSuccess()) {
            throw new TradeException(agentInfoResp.getCode(), agentInfoResp.getMessage());
        }
        return agentInfoResp;
    }

    /**
     * 获取交易路由数据：
     *
     * @param
     * @param
     * @return
     */
    protected RouteResp getRouteRiskTrade(BizContent bizContent, String bankCode) {
        RouteReq routeReq = new RouteReq(bizContent, bankCode);
        RouteResp routeResp = routeRiskApiService.getRouteByTradeRisk(routeReq);
        if (!routeResp.isSuccess()) {
            throw new TradeException(routeResp.getCode(), routeResp.getMessage());
        }
        return routeResp;
    }

    /**
     * 获取交易HTML：请求channel通道
     * 该请求是需要处理交易订单！
     *
     * @param bizContent  请求参数
     * @param onlineOrder 交易订单
     * @return
     */
    protected ChannelTradeResp requestHtml(BizContent bizContent, OnlineOrder onlineOrder) {
        ChannelTradeReq channelTradeReq = new ChannelTradeReq(bizContent);
        channelTradeReq.setTradeNum(onlineOrder.getTradeNum());
        channelTradeReq.setSerialNum(onlineOrder.getSerialNum());
        channelTradeReq.setChannelNo(onlineOrder.getChannelNo());
        channelTradeReq.setChannelBusinessNo(onlineOrder.getChannelBusinessNo());
        channelTradeReq.setMerchantRate(onlineOrder.getMerchantRateFee());
        channelTradeReq.setMerchantFee(onlineOrder.getMerchantFee());

        return channelTradeApiService.requestHtml(channelTradeReq);
    }

    /**
     * 验证商户是否在该机构下：
     *
     * @param agentNo
     * @param serialAgentNo
     * @return
     */
    protected void isAgentNo(String agentNo, String serialAgentNo) {
        if (!Objects.equals(agentNo, serialAgentNo)) {
            throw new TradeException(TradeErrorEnum.FREEZE_MERCHANT_ERROR);
        }
    }

    /**
     * 对外请求方法:交易类
     *
     * @param bizContent 订单参数
     * @return BaseResponse
     */
    @Override
    public BaseResponse execute(BizContent bizContent) {
        logger.info("服务接口：，该服务暂未实现：");
        return BaseResponse.error(TradeErrorEnum.REALIZE_SERVER_ERROR.getCode(),
                TradeErrorEnum.REALIZE_SERVER_ERROR.getMessage());
    }

    /**
     * 返回下游订单支付信息！
     *
     * @param bizContent
     * @param onlineOrder
     * @return
     */
    protected BaseResponse respOrderResult(BizContent bizContent, OnlineOrder onlineOrder) {
        OnlineOrderResp onlineOrderResp = new OnlineOrderResp(bizContent);
        onlineOrderResp.setStatus(onlineOrder.getStatus().name());
        onlineOrderResp.setTradeNum(onlineOrder.getTradeNum());
        return onlineOrderResp;
    }

}
